/*
 *  LLMatrix.h 
 *  LID Library
 *
 *  Created by Alexander Trutchenko on 11/01/12.
 *  Copyright 2012 League of Independent Developers. All rights reserved.
 *
 */

#ifndef __LL_Matrix_h__
#define __LL_Matrix_h__

////////////////////////////////////////////////////////
// Types

namespace lidlib {

////////////////////////////////////////////////////////
//
/** LLMatrix
*  It is a simple variant of square array[edgeSize][edgeSize]
*/
////////////////////////////////////////////////////////

template<typename T>
class LLMatrix
{
    unsigned int _edgeSize;
    T* _data;

public:
    LLMatrix(): _edgeSize(0), _data(0) {;} 
    LLMatrix(const LLMatrix& from)
    {
        _edgeSize = from._edgeSize;
        _data = new T[_edgeSize*_edgeSize];
        for (unsigned int i = 0; i < _edgeSize*_edgeSize; ++i)
        	_data[i] = from._data[i];
    }
    LLMatrix(unsigned int edgeSize, const T& initValue) : _edgeSize(0), _data(0)
    {
        resizeWithNewEdge(edgeSize, initValue);
    }
    ~LLMatrix() { delete [] _data; }

    void resizeWithNewEdge(unsigned int edgeSize)
    {
        delete [] _data;
        _edgeSize = edgeSize;
        _data = new T[_edgeSize*_edgeSize];
    }

    inline unsigned int size() const { return _edgeSize*_edgeSize; } 
    inline unsigned int edgeSize() const { return _edgeSize; }

    const T* operator[](unsigned int _stringPos) const
    {	
        if (_stringPos < _edgeSize)
            return (_data + _stringPos*_edgeSize);
        return 0;//NULL
    }

    T* operator[](unsigned int _stringPos)
    {	
        if (_stringPos < _edgeSize)
            return (_data + _stringPos*_edgeSize);
        return 0;//NULL
    }

    inline T& atLinearIndex(unsigned int index) { return _data[index]; }
    inline const T& atLinearIndex(unsigned int index) const { return _data[index]; }

    LLMatrix<T>& operator=(const LLMatrix<T>& src)
    {
        resizeWithNewEdge(src._edgeSize);
        memcpy(_data, src._data, sizeof(T)*_edgeSize*_edgeSize);
        return *this;
    }

    bool operator==(const LLMatrix<T>& _Right) const
    {
        if (this->size() != _Right.size())
            return false;
        for (unsigned int i = 0; i < this->size(); ++i)
            if (this->atLinearIndex(i) != _Right->atLinearIndex(i))
                return false;
        return true;
    }
};


}; // end namespace lidlib

#endif // __LL_Matrix_h__
